﻿// Lesson22_5.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <queue>
#include <utility>
#include <map>
#include <string>
#include <set>
#include <unordered_map>
#include <functional>

struct MyKeyType
{
	int id;
	std::string str;
	MyKeyType(int kid) :id(kid) {}

	friend bool operator ==(const MyKeyType& first, const MyKeyType& second)
	{
		return first.id == second.id && (first.str ==  second.str);
	}
};

//namespace std
//{
//	//名称空间侵入
//	template<> struct hash<MyKeyType>
//	{
//		using argument_type = MyKeyType;
//		using result_type = size_t;
//		result_type operator()(const argument_type& f) const
//		{
//			return std::hash<int>()(f.id);
//		}
//	};
//}

struct MyKeyTypeHash
{
	size_t operator()(const MyKeyType& f) const
	{
		size_t id_hash = std::hash<int>()(f.id);
		size_t str_hash = std::hash<std::string>()(f.str);

		return id_hash ^ (str_hash << 1);
	}
};


int main()
{
    std::cout << "Hello World!\n"; 

	//std::queue<int> queue;
	//queue.push(1);
	//queue.push(2);
	//queue.push(3);
	//queue.push(4);
	//queue.push(5);

	//for (size_t i = 0; i < length; i++)
	//{

	//}

	std::pair<std::string, int> myPair;
	myPair.first="Name";
	myPair.second=28;

	auto myPair2 = std::make_pair("Hello",2019);

	std::pair<std::pair<int, int>, std::vector<int> > pair2vector;
	pair2vector.first.first;

	auto[first, second] = myPair2;

	auto[first1, second2] = std::pair(std::string("world"),2008);


	std::map<std::string, std::string> str2str;
	auto ins_ret1 = str2str.insert(std::pair("A","AAAAA"));
	if (ins_ret1.second)
	{

	}
	auto ins_ret2 = str2str.insert(std::make_pair("A", "BBBB"));
	if(ins_ret2.second) //false
	{

	}

	auto ret = str2str.insert({"Hello","world"});

	auto ret2 = str2str.insert_or_assign("Hello","World2019");
	if (ret2.second)
	{
		std::cout << "Inserted" << std::endl;
	}
	else
	{
		std::cout << "Overwritten" << std::endl;
	}

	//str2str[std::string("Nice")] = std::string("Good");

	std::string s = str2str[std::string("VeryGood")];

	//emplace,emplace_hint
	str2str.emplace(std::make_pair("ok","good1"));
	str2str.emplace("ok", "good2");

	//C++17
	str2str.try_emplace("ok", "good good");

	for (auto it = str2str.begin();it!=str2str.end();++it)
	{
		std::cout << "key=" << it->first << ",value=" << it->second << std::endl;
	}



	for (auto kv : str2str)
	{
		if (kv.first == "ok")
		{
			break;
		}
	}

	for (auto& [key,value] : str2str)
	{

	}
	auto fIter=str2str.find("Hello");
	fIter->second = "you";
	str2str["Hello"] = "2019";

	str2str.erase(fIter);//如果迭代器不在容器里，则会抛异常
	str2str.erase("Hello");//如果不存在，则什么也不做

	str2str.count("Hello");

	std::map<std::string, std::string>::node_type node = str2str.extract("Hello");
	std::map<std::string, std::string> str2strx;
	str2strx.insert(std::move(node));

	str2strx.merge(str2str);


	std::multimap<std::string, std::string> multistr2str;
	multistr2str.insert(std::pair("hello","z"));
	multistr2str.insert(std::pair("hello", "x"));
	multistr2str.insert(std::pair("hello", "y"));

	auto iter_pair=multistr2str.equal_range("hello");
	for (auto it = iter_pair.first;it!=iter_pair.second;++it)
	{
		std::cout << it->first << "," << it->second << std::endl;
	}

	std::set<std::string> strset;
	strset.insert("hello");
	strset.insert("hello");
	strset.insert({"1","2","3","2"});


	std::unordered_map<int, std::string> hash_int2str;
	hash_int2str[1] = "hei";

	std::unordered_map<MyKeyType, std::string,MyKeyTypeHash> mykey2str;

	mykey2str.insert(std::make_pair(MyKeyType(2),"2222"));

	mykey2str.insert(std::make_pair(MyKeyType(9), "99999"));

}

template<class KEY,class VALUE>
bool operator <(const std::pair<KEY, VALUE>& lhs,const std::pair<KEY, VALUE>& rhs)
{
	if (lhs.first < rhs.first)
	{
		return true;
	}
	else
	{
		if (lhs.first > rhs.first)
		{
			return false;
		}
		else
		{
			return lhs.second < rhs.second;
		}
	}
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
